package com.cloudcentral.controller;

import com.cloudcentral.enums.UploadTypePath;
import com.cloudcentral.exception.FailureException;
import com.cloudcentral.properties.HWCloudProperties;
import com.cloudcentral.util.Result;
import com.cloudcentral.util.Utils;
import com.obs.services.ObsClient;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * Create by Administrator
 * 2023/11/24 14:16
 */
@Slf4j
@RestController
@RequestMapping("/file")
@Tag(name = "文件相关")
@EnableConfigurationProperties(HWCloudProperties.class)
public class FileController extends BaseController{
  private final HWCloudProperties properties;

  @Autowired
  public FileController(HWCloudProperties properties) {
    this.properties = properties;
  }

  @PostMapping("/uploadPCM")
  @Operation(summary = "上传PCM")
  public Result<String> uploadPCM(@RequestParam String pcm) throws Exception {
    UploadTypePath uploadTypePath = UploadTypePath.PCM;
    try (ObsClient obsClient = new ObsClient(properties.getAk(), properties.getSk(), properties.getEndpoint())) {
      String suffix = ".raw",
          name = StringUtils.join(System.currentTimeMillis(), Utils.randomStr(16)),
          md5 = Utils.md5(name).toUpperCase(),
          path = StringUtils.join(uploadTypePath.getPath(), "/", md5, suffix);
      obsClient.putObject(properties.getBucket(), path, new ByteArrayInputStream(Base64.getDecoder().decode(pcm)));
      return Result.ok(StringUtils.join(properties.getUri(), path));
    }
  }

  @PostMapping("/uploadCSV")
  @Operation(summary = "上传CSV")
  public Result<String> uploadCSV(@RequestParam String content) throws Exception {
    UploadTypePath uploadTypePath = UploadTypePath.BEST_DETECT_RESULT;
    try (ObsClient obsClient = new ObsClient(properties.getAk(), properties.getSk(), properties.getEndpoint())) {
      String suffix = ".csv",
          name = StringUtils.join(System.currentTimeMillis(), Utils.randomStr(16)),
          md5 = Utils.md5(name).toUpperCase(),
          path = StringUtils.join(uploadTypePath.getPath(), "/", md5, suffix);
      obsClient.putObject(properties.getBucket(), path, new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
      return Result.ok(StringUtils.join(properties.getUri(), path));
    }
  }

  @PostMapping("/uploadFile")
  @Operation(summary = "上传文件", parameters = {
      @Parameter(name = "type", description = """
          icon: 图标;
          avatar: 头像;
          background: 背景图;
          """, required = true),
      @Parameter(name = "file", description = "文件数组", required = true)
  })
  public Result<String> uploadFile(@RequestParam String type, @RequestPart MultipartFile file) throws Exception {
    UploadTypePath uploadTypePath = UploadTypePath.fromType(type);
    if (uploadTypePath == null) throw new FailureException("缺少上传类型");
    else if (file == null || file.isEmpty()) throw new FailureException("缺少文件");
    else if (file.getSize() > 1024 * 1024 * 1024) throw new FailureException("文件不能超过1G");
    else {
      try (ObsClient obsClient = new ObsClient(properties.getAk(), properties.getSk(), properties.getEndpoint())) {
        String filename = StringUtils.defaultIfBlank(file.getOriginalFilename(), file.getName()),
            suffix = filename.substring(filename.lastIndexOf(".")),
            name = StringUtils.join(System.currentTimeMillis(), Utils.randomStr(16)),
            md5 = Utils.md5(name).toUpperCase(),
            path = StringUtils.join(uploadTypePath.getPath(), "/", md5, suffix);
        obsClient.putObject(properties.getBucket(), path, file.getInputStream());
        return Result.ok(StringUtils.join(properties.getUri(), path));
      }
    }
  }

  @DeleteMapping("/delete")
  @Operation(summary = "删除文件")
  public Result<Boolean> delete(String uri) throws Exception {
    if (StringUtils.isBlank(uri)) return Result.ok(true);
    else {
      String prefix = properties.getUri();
      String path = uri.startsWith(prefix) ? uri.substring(prefix.length()) : uri;
      try (ObsClient obsClient = new ObsClient(properties.getAk(), properties.getSk(), properties.getEndpoint())) {
        obsClient.deleteObject(properties.getBucket(), path);
        return Result.ok(true);
      }
    }
  }
}
